package net.goutalk.glcs.module.erpModel.caseErpPurchase.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import net.goutalk.glcs.common.constant.GlobalConstant;
import net.goutalk.glcs.common.enums.YesOrNoEnum;
import net.goutalk.glcs.common.page.ConventPage;
import net.goutalk.glcs.common.page.PageOutput;
import net.goutalk.glcs.common.utils.RedisUtil;
import net.goutalk.glcs.module.erpModel.caseErpLog.entity.CaseErpLog;
import net.goutalk.glcs.module.erpModel.caseErpLog.service.ICaseErpLogService;
import net.goutalk.glcs.module.erpModel.caseErpPurchase.entity.CaseErpPurchase;
import net.goutalk.glcs.module.erpModel.caseErpPurchase.entity.CaseErpPurchaseDetail;
import net.goutalk.glcs.module.erpModel.caseErpPurchase.mapper.CaseErpPurchaseMapper;
import net.goutalk.glcs.module.erpModel.caseErpPurchase.service.ICaseErpPurchaseDetailService;
import net.goutalk.glcs.module.erpModel.caseErpPurchase.service.ICaseErpPurchaseService;
import net.goutalk.glcs.module.erpModel.caseErpPurchase.utils.DataUtil;
import net.goutalk.glcs.module.erpModel.caseErpPurchase.vo.CaseErpPurchaseCheckInfoVo;
import net.goutalk.glcs.module.erpModel.caseErpPurchase.vo.CaseErpPurchasePageVo;
import net.goutalk.glcs.module.erpModel.caseErpSale.dto.CaseErpSalePageDto;
import net.goutalk.glcs.module.erpModel.caseErpStock.vo.InStoreLogVo;
import net.goutalk.glcs.module.erpModel.caseErpStore.entity.CaseErpStoreReceipt;
import net.goutalk.glcs.module.erpModel.caseErpStore.service.ICaseErpStoreReceiptService;
import net.goutalk.glcs.module.erpModel.caseErpSupplier.entity.CaseErpSupplier;
import net.goutalk.glcs.module.erpModel.caseErpSupplier.service.ICaseErpSupplierService;
import net.goutalk.glcs.module.organization.entity.Department;
import net.goutalk.glcs.module.organization.entity.User;
import net.goutalk.glcs.module.system.entity.DictionaryDetail;
import net.goutalk.glcs.module.system.service.IDictionarydetailService;
import net.goutalk.glcs.module.workflow.entity.WorkflowFormRelation;
import net.goutalk.glcs.module.workflow.service.IWorkflowFormRelationService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 采购订单信息【case_erp_purchase】 服务实现类
 * </p>
 *
 * @author hnyyzy
 * @since 2023-06-21
 */
@Service
@AllArgsConstructor
public class CaseErpPurchaseServiceImpl extends MPJBaseServiceImpl<CaseErpPurchaseMapper, CaseErpPurchase> implements ICaseErpPurchaseService {

    private final ICaseErpPurchaseDetailService caseErpPurchaseDetailService;

    private final ICaseErpSupplierService caseErpSupplierService;

    private final RedisUtil redisUtil;

    private final ICaseErpLogService caseErpLogService;

    private final IDictionarydetailService dictionarydetailService;

    private final IWorkflowFormRelationService formRelationService;

    private final ICaseErpStoreReceiptService caseErpStoreReceiptService;


    @Override
    public PageOutput<CaseErpPurchasePageVo> getPageList(CaseErpSalePageDto dto) {
        LambdaQueryWrapper<CaseErpPurchase> queryWrapper = Wrappers.lambdaQuery(CaseErpPurchase.class)
                .like(StrUtil.isNotBlank(dto.getTheme()), CaseErpPurchase::getTheme, dto.getTheme())
                .orderByDesc(CaseErpPurchase::getCreateDate);
        IPage<CaseErpPurchase> page = this.page(ConventPage.getPage(dto), queryWrapper);
        List<CaseErpPurchasePageVo> caseErpPurchasePageVos = BeanUtil.copyToList(page.getRecords(), CaseErpPurchasePageVo.class);
        List<CaseErpPurchaseDetail> saleDetailList = caseErpPurchaseDetailService.list();
        List<CaseErpPurchasePageVo> convert = this.convert(caseErpPurchasePageVos, saleDetailList);

        PageOutput<CaseErpPurchasePageVo> output = new PageOutput<>();
        output.setCurrentPage(dto.getLimit());
        output.setPageSize(dto.getSize());
        output.setTotal(saleDetailList.size());
        output.setList(convert);

        return output;
    }

    @Override
    public List<CaseErpPurchasePageVo> importByIds(List<Long> ids) {
        List<CaseErpPurchase> list = this.list(Wrappers.<CaseErpPurchase>query().lambda().in(CaseErpPurchase::getId,ids));
        List<CaseErpPurchaseDetail> saleDetailList = caseErpPurchaseDetailService.list();
        List<CaseErpPurchasePageVo> salePageVoList = BeanUtil.copyToList(list, CaseErpPurchasePageVo.class);
        List<CaseErpPurchasePageVo> convert = this.convert(salePageVoList, saleDetailList);
        return convert;
    }

    @Override
    public CaseErpPurchaseCheckInfoVo checkInfo(Long id) {
        CaseErpPurchase purchase = this.getById(id);
        CaseErpPurchasePageVo caseErpPurchasePageVo = BeanUtil.toBean(purchase, CaseErpPurchasePageVo.class);
        List<CaseErpPurchaseDetail> saleDetailList = caseErpPurchaseDetailService.list();
        List<CaseErpPurchasePageVo> caseErpPurchasePageVoList = new ArrayList<>();
        caseErpPurchasePageVoList.add(caseErpPurchasePageVo);
        List<CaseErpPurchasePageVo> convert = this.convert(caseErpPurchasePageVoList, saleDetailList);
        CaseErpPurchaseCheckInfoVo infoVo = new CaseErpPurchaseCheckInfoVo();
        if (CollectionUtil.isNotEmpty(convert)){
            infoVo = BeanUtil.toBean(convert.get(0),CaseErpPurchaseCheckInfoVo.class);
        }
        // 采购详情
        List<CaseErpPurchaseDetail> purchaseDetailList = caseErpPurchaseDetailService.list(Wrappers.
                <CaseErpPurchaseDetail>query().lambda().eq(CaseErpPurchaseDetail::getPurchaseId, id));
        infoVo.setCaseErpPurchaseDetailList(purchaseDetailList);

        // 入库记录
        //拿订单的id去出入库单据表查询，有无关联数据，有的话就展示
        List<InStoreLogVo> inStoreLogVos = new ArrayList<>();
        List<CaseErpStoreReceipt> list = caseErpStoreReceiptService.list(Wrappers.<CaseErpStoreReceipt>query().lambda().eq(CaseErpStoreReceipt::getRelationKeyId, id));
        if (CollectionUtil.isNotEmpty(list)) {//真数据
            for (CaseErpStoreReceipt caseErpStoreReceipt : list) {
                InStoreLogVo inStoreLogVo = new InStoreLogVo();
                inStoreLogVo.setId(caseErpStoreReceipt.getId());
                inStoreLogVo.setCode(caseErpStoreReceipt.getCode());
                inStoreLogVo.setTheme(caseErpStoreReceipt.getName());
                inStoreLogVo.setDate(caseErpStoreReceipt.getCreateDate());
                inStoreLogVo.setName("客户一");
                inStoreLogVo.setPerson(caseErpStoreReceipt.getPersonNames());
                inStoreLogVo.setStore("仓库一");
                inStoreLogVos.add(inStoreLogVo);
            }
        }
        infoVo.setInStoreLogVoList(inStoreLogVos);

        // 到票记录
        infoVo.setTicketLogVoList(DataUtil.buildTicketLogList(id));
        // 付款记录
        infoVo.setPayLogVoList(DataUtil.buildPayLogList(id));
        // 操作记录
        List<CaseErpLog> logList = caseErpLogService.list(Wrappers.<CaseErpLog>query().lambda()
                .eq(CaseErpLog::getCategoryId, 2)
                .eq(CaseErpLog::getKeyId, id)
                .orderByDesc(CaseErpLog::getCreateDate));
        infoVo.setLogList(logList);

        //审批记录，先看有没有关联申请单，有就查询改申请单的状态
        if (ObjectUtil.isNotEmpty(purchase.getApplyId())){
            //查询申请状态,如果存在，则有审批记录，返回processId给前端，前端再调/process/all-record进行查询
            String formId = "1681934131747237888";
            String formKeyValue = purchase.getApplyId().toString();
            List<WorkflowFormRelation> relations = formRelationService.list(Wrappers.lambdaQuery(WorkflowFormRelation.class)
                    .eq(WorkflowFormRelation::getFormId, formId).eq(WorkflowFormRelation::getFormKeyValue, formKeyValue));
            if (CollectionUtil.isNotEmpty(relations) && StrUtil.isNotBlank(relations.get(0).getProcessId())){
                infoVo.setProcessInstanceId(relations.get(0).getProcessId());
                infoVo.setFlowStatus(YesOrNoEnum.YES.getCode());//已发起审批
            }else {
                infoVo.setFlowStatus(YesOrNoEnum.NO.getCode());//未发起审批
            }
        }else {
            infoVo.setFlowStatus(YesOrNoEnum.NO.getCode());//未发起审批
        }

        return infoVo;
    }

    public List<CaseErpPurchasePageVo> convert(List<CaseErpPurchasePageVo> caseErpPurchasePageVos,List<CaseErpPurchaseDetail> saleDetailList){
        List<CaseErpSupplier> caseErpSupplierList = caseErpSupplierService.list();
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        List<Department> departmentList = redisUtil.get(GlobalConstant.DEP_CACHE_KEY, new TypeReference<List<Department>>() {
        });

        List<DictionaryDetail> dictionaryDetailList = dictionarydetailService.list();

        for (CaseErpPurchasePageVo caseErpPurchasePageVo : caseErpPurchasePageVos) {
            StringBuilder detailStr = new StringBuilder();
            for (CaseErpPurchaseDetail caseErpPurchaseDetail : saleDetailList) {
                if (ObjectUtil.equals(caseErpPurchasePageVo.getId(), caseErpPurchaseDetail.getPurchaseId())) {
                    detailStr.append(StringPool.COMMA);
                    detailStr.append(caseErpPurchaseDetail.getName());
                    detailStr.append(StringPool.COLON + StringPool.SPACE);
                    detailStr.append(String.format("%.0f", caseErpPurchaseDetail.getCount()));
                }
            }
            if (detailStr.length() > 0) {
                detailStr.delete(0, 1);
            }
            caseErpPurchasePageVo.setPurchaseDetail(detailStr.toString());
            if (ObjectUtil.isEmpty(caseErpPurchasePageVo.getInStoreState())){
                caseErpPurchasePageVo.setInStoreState(YesOrNoEnum.NO.getCode());
            }
            if (ObjectUtil.isNotEmpty(caseErpPurchasePageVo.getSupplierId())) {
                CaseErpSupplier caseErpSupplier = caseErpSupplierList.stream().filter(x -> x.getId().equals(caseErpPurchasePageVo.getSupplierId())).findFirst().orElse(new CaseErpSupplier());
                if (StrUtil.isNotBlank(caseErpSupplier.getName())) {
                    caseErpPurchasePageVo.setSupplierName(caseErpSupplier.getName());
                }
            }
            if (ObjectUtil.isNotEmpty(caseErpPurchasePageVo.getPurchasePersonId())) {
                User user = userList.stream().filter(x -> x.getId().equals(caseErpPurchasePageVo.getPurchasePersonId())).findFirst().orElse(new User());
                if (StrUtil.isNotBlank(user.getName())) {
                    caseErpPurchasePageVo.setPurchasePersonName(user.getName());
                }
            }
            if (ObjectUtil.isNotEmpty(caseErpPurchasePageVo.getPurchaseDeptId())) {
                Department department = departmentList.stream().filter(x -> x.getId().equals(caseErpPurchasePageVo.getPurchaseDeptId())).findFirst().orElse(new Department());
                if (StrUtil.isNotBlank(department.getName())) {
                    caseErpPurchasePageVo.setPurchaseDeptName(department.getName());
                }
            }
            if (ObjectUtil.isNotEmpty(caseErpPurchasePageVo.getRelatedProject())){
                DictionaryDetail dictionaryDetail = dictionaryDetailList.stream().filter(x -> x.getId().equals(caseErpPurchasePageVo.getRelatedProject())).findFirst().orElse(new DictionaryDetail());
                if (StrUtil.isNotBlank(dictionaryDetail.getName())) {
                    caseErpPurchasePageVo.setRelatedProjectName(dictionaryDetail.getName());
                }
            }
            if (ObjectUtil.isNotEmpty(caseErpPurchasePageVo.getPayType())){
                DictionaryDetail dictionaryDetail = dictionaryDetailList.stream().filter(x -> x.getId().equals(caseErpPurchasePageVo.getPayType())).findFirst().orElse(new DictionaryDetail());
                if (StrUtil.isNotBlank(dictionaryDetail.getName())) {
                    caseErpPurchasePageVo.setPayTypeName(dictionaryDetail.getName());
                }
            }
            if (ObjectUtil.isNotEmpty(caseErpPurchasePageVo.getCreateUserId())) {
                User user = userList.stream().filter(x -> x.getId().equals(caseErpPurchasePageVo.getCreateUserId())).findFirst().orElse(new User());
                if (StrUtil.isNotBlank(user.getName())) {
                    caseErpPurchasePageVo.setCreateUserName(user.getName());
                }
            }
            if (ObjectUtil.isNotEmpty(caseErpPurchasePageVo.getModifyUserId())) {
                User user = userList.stream().filter(x -> x.getId().equals(caseErpPurchasePageVo.getModifyUserId())).findFirst().orElse(new User());
                if (StrUtil.isNotBlank(user.getName())) {
                    caseErpPurchasePageVo.setModifyUserName(user.getName());
                }
            }
        }

        return caseErpPurchasePageVos;
    }
}
